package org.zn.note.spring.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;

import javax.sql.DataSource;

/**
 * 关于SpringBoot的自动配置
 * <p>
 * 在Spring中有两种配置：
 * 1、Bean装配：声明在Spring上下文中创建哪些组件，以及如何相互注入
 * 2、属性注入：声明Spring Bean中的属性的值
 * 在Spring中无论是XML还是Java配置，都有明确的设置。
 * <p>
 * {@link #dataSource()}
 * 是使用Java配置，在代码里写出了配置信息。这就是在没有SpringBoot时，Spring要写的配置。
 * 而SpringBoot则不用，它会发现h2的依赖，然后创建DataSource Bean，这个Bean默认执行(默认配置)schema.sql、data.sql
 * 那如果我们使用SpringBoot，又想执行别的sql文件呢？在哪可以修改这个配置呢？
 * <p>
 * SpringBoot 会“汇总”各个属性源的属性，统一放到Spring环境中，然后再从Spring环境中注入到Spring Bean属性中：
 * ① JVM系统属性
 * ② 操作系统环境变量               (export SERVER_PORT=8080)
 * ③ 命令行参数                    (java -jar xxxx.jar --server.port=8080)
 * ④ Application.properties/yml   (server.port=8080)
 * --- [选择、优先级、覆盖汇总] ---> Spring环境 ---> Bean属性
 * （Spring从上述属性数据源，根据一定规则，抽取数据到Spring环境中，然后根据Bean的属性装配需要，将数据赋值给对应的属性）
 * <p>
 * Spring如何消费这些属性呢（将数据注入到Bean属性中）？
 * {@link org.zn.note.spring.data.OrderProps}
 * <p>
 * Spring Profile 条件化配置
 * 两种方式：
 * 1、分成不同的文件：application-{profile名字}.yml
 * 2、在一个文件里，用 --- 分开（仅用于yaml格式），application.yml.bak 就是这样的例子
 * 激活profile：
 * 1、spring.profiles.active: -prod  不推荐
 * 2、环境变量 export SPRING_PROFILES_ACTIVE=prod
 * 3、启动参数 java -jar xxx.jar --spring.profiles.active=dev,test
 * <p>
 * 条件化创建Bean ！  就是下面创建数据源这个例子，在开发环境用h2
 */
// 注意，这个类仅仅是记录用的，所以没加 @Configuration，所以怎么写都不起作用
public class SpringBootConfig {
    @Bean
    @Profile("dev")
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .addScript("schema.sql")
                .addScripts("data1.sql", "data2.sql")
                .build();
    }
}
